﻿using System;
using NDasm.Core.UI.Base;
using Mono.Cecil;
using Mono.Cecil.Cil;

namespace NDasm.Core.UI.MethodDasm
{
    public class InstructionViewModel : ViewModel
    {
        private readonly Instruction instruction;

        public InstructionViewModel(Instruction instruction)
        {
            this.instruction = instruction;
            IsJumpInstruction = instruction.Operand is Instruction;
        }

        public string Offset
        {
            get { return OffsetToString(instruction.Offset); }
        }

        public string OpCode
        {
            get { return instruction.OpCode.ToString(); }
        }

        public string Operand
        {
            get { return GetOperand(); }
        }

        public bool IsJumpInstruction { get; private set; }

        private bool simpleMethodName;
        public bool SimpleMethodName
        {
            get { return simpleMethodName; }
            set
            {
                simpleMethodName = value;
                NotifyPropertyChanged(() => SimpleMethodName);
                NotifyPropertyChanged(() => Operand);
            }
        }

        public int RawOffset
        {
            get { return instruction.Offset; }
        }

        public int JumpOffset
        {
            get { return IsJumpInstruction ? ((Instruction)instruction.Operand).Offset : 0; }
        }

        private string GetOperand()
        {
            if (instruction.Operand == null)
                return string.Empty;
            if (SimpleMethodName)
            {
                MethodReference method = instruction.Operand as MethodReference;
                if (method != null)
                    return string.Format("{0}.{1}()", method.DeclaringType.Name, method.Name);
            }
            if (IsJumpInstruction)
                return OffsetToString(JumpOffset);
            return instruction.Operand.ToString();
        }

        private string OffsetToString(int offset)
        {
            return String.Format("IL_{0}", offset.ToString("X4"));
        }
    }
}
